const {
    json,
    isEmpty,
    readFile,
    getAddress
} = require("../../utils/index");
const {
    insertLogInfo
} = require("../../utils/log-tools")
const {
    query
} = require("../../db")
const {
    v4: uuidv4
} = require("uuid")
// 发送邮件的依赖
const nodemailer = require("nodemailer");
// md5加密
const bcryptjs = require("bcryptjs");
// jwt生成token
const jwt = require("jsonwebtoken");
// 导入配置文件
const configs = require("../../config");
const path = require("path");

// 定义一些常量
const THEME_CONFIG_PATH = path.join(process.cwd(),"/configs","/theme.json");
const ARTICLE_PATH = path.join(process.cwd(),'/article');

// 1. 获取文章列表
exports.list = (req, res) => {
    const {
        pageNum,
        pageSize,
        articleTitle,
        startTime,
        endTime,
        type,
        label
    } = req.query;
    const condition = [
        isEmpty(articleTitle) ? "1=1 and " : `article_title like '%${articleTitle}%' and `,
        isEmpty(type) ? "1=1 and " : `type='${type}' and `,
        isEmpty(label) ? "1=1 and " : `label like '%${label}%' and `,
        isEmpty(startTime) || isEmpty(endTime) ? "1=1 and " : `(create_time>=${startTime} and create_time<=${endTime}) and `,
        `status=0 and is_draft=0 `,
        `order by create_time desc limit ${(pageNum - 1) * pageSize},${pageSize}`
    ]
    const sqlStr = `select * from t_article where ${condition.join("")}`;
    let result1 = {}
    query(sqlStr, "").then(result => {
        result1 = result
        return query("select count(*) as count from t_article where is_draft=0 and status=0")
    }).
        then(result => {
            res.send(json("success", 0, {
                data: result1,
                tatal: result[0].count
            }));
        }).
        catch(err => {
            insertLogInfo(0, err);
            res.send(json("sql错误"));
        })
}

// 2. 获取主题配置信息
exports.themeInfo = (req, res) => {
    readFile(THEME_CONFIG_PATH).then(data => {
        res.send(json("success", 0, JSON.parse(data.toString())));
    }).catch(err => {
        insertLogInfo(0, err);
        return res.send(json("服务器异常"));
    })
}

// 获取标签列表
exports.getLabelList = (req, res) => {
    const sql_select = "select id,label_name,belongs_type,annotation from t_label";
    query(sql_select).then(result => {
        res.send(json("success", 0, result));
    }).catch(err => {
        insertLogInfo(0, err);
        res.send(json("sql错误"));
    });
}

// 获取类型列表
exports.getTypeList = (req, res) => {
    const sql_select = "select id,type_name,annotation from t_type";
    query(sql_select).then(result => {
        res.send(json("success", 0, result));
    }).catch(err => {
        insertLogInfo(0, err);
        res.send(json("sql错误"));
    });
}

// 通过id获取文章详情数据
exports.article = (req, res) => {
    const {
        id
    } = req.query;
    let resultData = {}
    const sql_select = `select * from t_article where id='${id}'`;
    query(sql_select).then(result => {
        resultData = result[0]
        return readFile(path.join(ARTICLE_PATH,resultData.path));
    }).
        then((data) => {
            res.send(json("success", 0, {
                ...resultData,
                content: new String(data)
            }));
        }).catch(err => {
            insertLogInfo(0, err);
            res.send(json("sql错误"));
        });
}

// 获取文章全部列表信息，只有基本信息
exports.articleInfo = (req, res) => {
    const sql_select = 'select id,article_title,create_time,type,label from t_article where status=0 and is_draft=0 order by create_time desc';
    query(sql_select).then(result => {
        let timeMap = {}
        const fillZero = v => v < 10 ? "0" + v : v
        result.forEach(item => {
            let date = new Date(item.create_time)
            let year = date.getFullYear()
            let month = fillZero(date.getMonth() + 1)
            let time = year + "年" + month + "月"
            if (!timeMap[time]) {
                timeMap[time] = []
            }
            timeMap[time].push(item)
        })
        res.send(json("success", 0, timeMap));
    }).catch(err => {
        insertLogInfo(0, err)
        res.send(json("sql错误"))
    })
}

// 获取服务器信息
exports.serverInfo = (req, res) => {
    let server_info = require("../../configs/server_info.json")
    res.send(json("success", 0, server_info))
}


var register_email = {} // 存注册验证码的邮箱
var register_codes = {} // 存注册验证码
// 发送邮箱验证码
exports.send_code = (req, res) => {
    const email = req.body.user_email;
    if (!register_email[email]) {
        // 验证该邮箱是否已经注册
        const sql_select = `select id from t_user where user_email='${email}'`
        query(sql_select).then(result => {
            if (result && result.length == 1) {
                res.send(json("该邮箱已经注册"))
            }
        }).catch(err => {
            insertLogInfo(0, err)
            res.send(json("sql错误"))
        })

        let numbers = "abcdefghijklmnopqrstuvwsyz0123456789"
        let code = ""
        for (let i = 0; i < 6; i++) code += numbers[Math.floor(Math.random() * 36)];
        register_email[email] = code;
        register_codes[code] = {
            email,
            timeout: undefined
        };
        // 发送
        let transporter = nodemailer.createTransport({
            service: "QQ",
            auth: {
                user: '2289538564@qq.com',
                pass: "xxxx"
            }
        });
        transporter.sendMail({
            from: "CemCode博客主邮箱 <2289538564@qq.com>",
            subject: "注册验证码",
            to: email,
            html: `<strong style="padding:10px;font-size:30px">${code}</strong>`
        }, err => {
            if (err) {
                res.send(json("邮件发送失败: " + err));
                console.log("邮件发送失败", err);
            }
            res.send(json("success", 0, "发送成功"));
        });
        setTimeout(() => {
            delete register_email[email];
            // 限制该邮箱在1分钟内只能获取一次邮箱验证码
            if (register_codes[code]) {
                register_codes[code].timeout = setTimeout(() => {
                    // 10分钟才清理掉这个code
                    clearTimeout(register_codes[code].timeout);
                    delete register_codes[code];
                }, 10 * 60000)
            }
        }, 60000)
    } else {
        res.send(json("验证码发送频繁,请稍后再试"));
    }
}


// 注册账号
// 注: 这种写法并没有兼容第三方平台登录并自动注册
// 因为registration_platform为1时也会检测code(验证码)，这显然是不行的，所以应该在第三方登录时（第三方登录必定会传第三方code(类似token)到后端）
// 然后后端拿这个code(类似token)请求第三方拿到token，这个时候才算登录成功，这个时候也会顺便利用邮箱注册一个用户账号，如果registration_platform为1
// 则会拿token做校验是否是第三方登录的账号。
exports.register = (req, res) => {
    const {
        pwd,
        user_email,
        user_name,
        registration_platform,
        code
    } = req.body;
    const id = uuidv4().replace(/-/g, "");
    if (!pwd && registration_platform == 0) {
        // 如果是平台注册则必须要输入密码
        res.send(json("请输入密码"));
    } else if (register_codes[code]?.email === user_email) {
        // 邮箱和验证码都正确,直接新增数据
        let password = "";
        if (pwd) {
            password = bcryptjs.hashSync(pwd, 15);
        }
        const sql_insert = `insert into t_user (id,user_name,user_email,password,create_time,modify_time,status,registration_platform) values(?,?,?,?,?,?,?,?)`;
        query(sql_insert, [id, user_name, user_email, password, new Date(), new Date(), 0, registration_platform]).then((result) => {
            // 先注销该验证码
            if (register_codes[code]) {
                clearTimeout(register_codes[code].timeout);
                delete register_codes[code];
            }
            if (result.affectedRows == 1) {
                res.send(json("success", 0, "注册成功"));
            } else {
                res.send(json("注册失败"));
            }
        }).catch(err => {
            insertLogInfo(0, err)
            res.send(json("sql错误"))
        })
    } else {
        // 验证码错误
        res.send(json("验证码错误"));
    }
}

// 用户登录
exports.login = (req, res) => {
    const {
        pwd,
        user_email,
        user_name,
        login_platform
    } = req.body;
    console.log(login_platform);
    switch (login_platform) {
        case "0": // 本平台
            const sql_select = `select id,user_name,user_email,password from t_user where user_email='${user_email}' and user_name='${user_name}' and status=0`;
            query(sql_select).then((result) => {
                if (result.length == 1) {
                    if (bcryptjs.compareSync(pwd, result[0].password)) {
                        // 密码正确,生成有效token
                        let user_token = jwt.sign({
                            ...result[0]
                        }, configs.jwtSecretKey, {
                            expiresIn: configs.expiresIn
                        });
                        res.send(json("success", 0, {
                            token: user_token,
                            id: result[0].id
                        }))
                    } else {
                        res.send("密码错误");
                    }
                } else {
                    res.send("邮箱或用户名不存在");
                }
            })
            break;

        case "1": // github

        default:
            res.send("登录失败");
    }
}

// 新增用户评论
exports.send_comment = (req, res) => {
    try {
        let _json = jwt.verify(req.headers.user_token, configs.jwtSecretKey);
        let address = "";
        getAddress(req.request_ip).then(result => {
            address = result;
        }).catch(err => {
            insertLogInfo(0, err)
        }).finally(() => {
            // 不管有无获取到范围地址都要进行操作
            const id = uuidv4().replace(/-/g, "");
            const sql_select = `select id from t_article where id='${req.body.article_id}'`;
            const sql_select_2 = `select relation from t_comment where id='${req.body?.comment_id}'`;
            const sql_select_4 = `select count(*) count from t_comment where article_id=? and reply_comment_id=?`
            const sql_insert = `insert into t_comment value(?,?,?,?,?,?,?,?,?,?,?,?,?)`;


            // 查询子集数量
            let querySubsetNumber = function (type) {
                let value = type == 0 ? [req.body.article_id, req.body.comment_id] : [req.body.article_id, ''];
                return query(sql_select_4, value);
            }

            // 插入评论数据
            let insertComment = function (relation, reply_comment_id = '') {
                query(sql_insert, [id, _json.user_name, _json.user_email, req.request_ip, address, req.body.comment,
                    new Date(), new Date(), 0, relation, reply_comment_id, req.body.article_id, 0
                ]).then(result => {
                    if (result.affectedRows == 1) {
                        // 插入数据成功
                        res.send(json("success", 0, "数据添加成功"));
                    } else {
                        throw new Error("数据添加失败");
                        // res.send(json("数据添加失败"));
                    }
                }).catch(err => { throw err });
            }

            // 1.先校验该文章id是否存在
            query(sql_select).then(result => {
                if (result?.length > 0) {
                    if (req.body.comment_id) {
                        // 2.如果评论id存在代表是嵌套评论，查看该评论是否存在
                        return query(sql_select_2);
                    } else {
                        // 3.如果评论id不存在，则代表是第一层的评论
                        querySubsetNumber(1).then(result => {
                            let numbers = result[0].count + 1;
                            let relation = '' + numbers + '-';
                            // 添加数据
                            insertComment(relation);
                        }).catch(err => { throw err });
                        // 结束then
                        return Promise.reject(new Error("success"));
                    }
                } else {
                    throw new Error("文章id不存在");
                }
            }).then(result => {
                // 评论存在，代表是嵌套评论
                if (result?.length > 0) {
                    let relation = result[0].relation;
                    querySubsetNumber(0).then(result => {
                        let numbers = result[0].count + 1;
                        relation += `${numbers}-`;
                        // 添加数据
                        insertComment(relation, req.body.comment_id);
                    }).catch(err => { throw err });
                } else {
                    throw new Error("评论主体不存在");
                }
            }).catch(err => {
                // 这里是为了处理中途完成非异常退出的情况
                if (err.message != 'success') {
                    insertLogInfo(0, err);
                    res.send(err.toString());
                }
            })
        })
    } catch (err) {
        insertLogInfo(0, err);
        res.send("无效token");
    }
}

// 获取文章评论
exports.article_comment = (req, res) => {
    const { article_id, page_num, page_size, comment_id } = req.query;
    
    const sql_select_relation =  `select relation from t_comment where article_id = '${article_id}' and comment_id='${comment_id}'`;
    let sql_select_1 = `
    select id,user_name,
    case 
        when status=0 then comment_message
        else '该评论已被屏蔽'
    end as comment_message,relation from t_comment
    where article_id = '${article_id}' ${comment_id ? `and id='${comment_id}'` : "and relation regexp '^[0-9]+-$'"} order by create_time asc limit ${(page_num - 1) * page_size},${page_size}
    `;
    let relation = "";

    if(comment_id && comment_id!=""){
        query(sql_select_relation).then(result=>{
            if(result?.length> 0){
                relation = result[0].relation;
                
                return query(sql_select_1);
            }else{
                throw new Error("评论不存在");
            }
        }).then(result => {
            res.send(json("success", result));
        }).catch (err=>{
            insertLogInfo(0, err);
            res.send(err.toString());
        });
    }

    // 查询评论
    function getComment(){
        return 
    }

    // 直接按照层级顺序查
    query(sql_select_1).then(result => {
        res.send(json("success", result));
    }).catch (err=>{
        insertLogInfo(0, err);
        res.send(err.toString());
    });
}